package Groep3;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Scanner;

public class P2Pclient implements Runnable {
	
	
	private Socket clientSocket;
	private ServerSocket idleSocket;
	private BufferedReader inFromUser;
	private BufferedReader inFromOther;
	private DataOutputStream outToOther;
	private String[] buffer;
	private int sequanceNumber;
	private int ackNumber;
	
	
	
	public P2Pclient(ServerSocket idleSocket2) throws Exception {
		//sequanceNumber = (int)(100*Math.random());
		//buffer = new ArrayList<String>();
		buffer = new String[8];
		idleSocket = idleSocket2;
		run();
		//receive2();
		//connect();
	}


	@Override
	public void run() {
		try{	        
			while(true){
				clientSocket = idleSocket.accept();
				inFromOther = new BufferedReader( new InputStreamReader( clientSocket.getInputStream() ));
				outToOther = new DataOutputStream( clientSocket.getOutputStream() );
				readFromClient();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
				
		
		
		
		
		
//		// TODO Auto-generated method stub
//		try {
//			//DataInputStream inFromOther;
//			clientSocket = idleSocket.accept();
//		
//			
//			inFromOther = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//			//toClient = new DataOutputStream(s.getOutputStream());
//
//			
//			
//			while(true){
//			System.out.println("Rec:"+readFromClient());
//			}
//		}
//		catch(Exception ex){
//			ex.printStackTrace();
//		}
	}


	private String readFromClient() {
		// TODO Auto-generated method stub
		String message = "";
		
		try {
			System.out.println("try to read from client");
			do {
				while(clientSocket.isConnected()== true){

					message =inFromOther.readLine();
					
					if (message.substring(0,1).equalsIgnoreCase("d")){
						System.out.println("Data overdracht");
						int ackN = Integer.parseInt(message.substring(2, 3));
						buffer[ackN] = message;
						System.out.println(message);
						//if(buffer.equals("ack " + ackNumber)) {
						ackNumber++;
							outToOther.writeBytes("a"+sequanceNumber + ackNumber+ "\n");
						//}
					}
					if (message.substring(0,1).equalsIgnoreCase("a")){
						System.out.println(message);
						ackNumber++;
						outToOther.writeBytes("a"+sequanceNumber + ackNumber+ "\n");
					}
					if (message.substring(0,1).equalsIgnoreCase("n")){
						System.out.println(message);
						ackNumber = Integer.parseInt(message.substring(2, 3));
						ackNumber++;
						outToOther.writeBytes("nack " + ackNumber+ '\n');
						}
					if (message.substring(0,1).equalsIgnoreCase("l")){
						System.out.println(message);
						System.out.println("TimeOut");
						//TODO:timer laten aflopen en pakket opnieuw versturen.
						int ackN = Integer.parseInt(message.substring(2, 3));
							outToOther.writeBytes("nack " + ackN + '\n');
							ackN++;
					}
					if (message.substring(0,1).equalsIgnoreCase("c")){
						System.out.println("ChecksumError");
						System.out.println(message);
						int ackN = Integer.parseInt(message.substring(2, 3));
						outToOther.writeBytes("nack " + ackNumber+ '\n');
						ackN++;
					}
					outToOther.flush();
//				case(2): System.out.println("FrameArrival");
//				if(/*Dataframe*/ ){
//						if (/*onverwacht sequencenr and geen Nak verstuurd voor huidig FrameExpected*/){	
//							// TODO: stuur Nakframe;
//						}
//						if(/*sequencenr in receiving window and nog niet geaccepteerd*/){	
//	//TODO:								plaats frame in buffer;
////									frames aan onderkant rec. win. naar NL;
////									aanpassen window administratie;
////									voor elk frame start/reset Acktimer;
//						}
//						if	(/*Nak (of 3 x dupl. Ack)and gevraagd sequencenr. zit in sending window*/){ 
//							
//						//TODO: stuur aangeduid frame opnieuw;
//						}
//	
//						// afrondende acties voor bovenstaande arrivals
//						// en na ontvangst van expliciet Ackframe
//							//TODO: stop timer(s) van bevestigde frame(s) en schuif ondergrens van sending window op;
//	
	}
				


			} while (message.length() < 0);
			} catch (Exception e) {
			System.out.println("Read client socket error: " + e);
			e.printStackTrace();
		}

		
		try { 
			if (message == null) { 
				clientSocket.close(); 
			} 
		} catch (IOException e) { 
			System.out.println("Close connection error: " + e); 
		}
		 
		return message;
	}
}
	
	//-------------------------------- Verbinding maken en berichten verzenden --------------------------------
	
//	
//	public void connect() throws Exception {
//		System.out.println("Typ 'connect' om verbinding te openen");
//		inFromUser = new BufferedReader(new InputStreamReader(System.in));
//		Scanner in = new Scanner(System.in);
//		if(in.nextLine().equals("connect")) {
//			idleSocket.close();
//			clientSocket = new Socket("localhost", 6789);
////			run();
////			receive2();
//		}
//		else {
//			System.out.println("Not connected...");
//			connect();
//		}
//	}
//	
//	
//	public void run() throws Exception {
//		
////		inFromUser = new BufferedReader(new InputStreamReader(System.in));
////		clientSocket = new Socket("localhost", 6789);
//		outToOther = new DataOutputStream(clientSocket.getOutputStream());
//		inFromOther = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//		while(true) {
//			
//			String sendThis;
//			Scanner in = new Scanner(System.in);
//			System.out.println("Voer bericht in:");
//			sendThis = in.nextLine();
//		
//			send(sendThis);
//		}
//	}
//	
//	public void send(String sendThis) throws Exception {
//		outToOther.writeBytes("Seq=" + sequanceNumber + '\n' + "ACK=" + ackNumber + '\n' + sendThis);
//		sequanceNumber++;
//	}
//	
//	//-------------------------------- /Verbinding maken en berichten verzenden --------------------------------
//	
//	
//	//-------------------------------- Naar inkomende berichten zoeken --------------------------------
//	
//	
//	public void receive2() throws Exception {
//		while(true) {
//			buffer.add(inFromOther.readLine());
//			String message = buffer.get(buffer.size());
//			System.out.println(message);
//		}
//	}
//	
//	
////	public void receive() throws Exception {
////		//TODO: timer instellen
////		while(true) {
////			
////			buffer.add(inFromOther.readLine());
////			String message = buffer.get(buffer.size());
////			if(message.equals("")) {
////				
////			}
////			
//////			wait();
////			int state = 0;
////			switch(state) {
////			case(1): System.out.println("NetworkLayerReady");
////			buffer.add(inFromOther.readLine());
////			if(buffer.get(0).equals("ack " + ackNumber)) {
////				send("ack " + ackNumber);
////			}
////			else {
////				System.out.println("Handshake error");
////			}
////			case(2): System.out.println("FrameArrival");
////			if(/*Dataframe*/ ){
////					if (/*onverwacht sequencenr and geen Nak verstuurd voor huidig FrameExpected*/){	
////						// TODO: stuur Nakframe;
////					}
////					if(/*sequencenr in receiving window and nog niet geaccepteerd*/){	
//////TODO:								plaats frame in buffer;
//////								frames aan onderkant rec. win. naar NL;
//////								aanpassen window administratie;
//////								voor elk frame start/reset Acktimer;
////					}
////					if	(/*Nak (of 3 x dupl. Ack)and gevraagd sequencenr. zit in sending window*/){ 
////						
////					//TODO: stuur aangeduid frame opnieuw;
////					}
////
////					// afrondende acties voor bovenstaande arrivals
////					// en na ontvangst van expliciet Ackframe
////						//TODO: stop timer(s) van bevestigde frame(s) en schuif ondergrens van sending window op;
////
////			}
////			
////			case(3): System.out.println("ChecksumError");
////			send("nack " + ackNumber);
////			case(4): System.out.println("TimeOut");
////			//TODO:timer laten aflopen en pakket opnieuw versturen.
////			
////			send("nack " + ackNumber);
////			case(5): System.out.println("NetworkLayerIdle");
////			//TODO: stuur acks van recieving window
////			
////			default: System.out.println("Error");
////			}
////		}
////	}
//	//TODO: state in receive() methode verranderen

	//-------------------------------- /Naar inkomende berichten zoeken --------------------------------	
	
	
	//-------------------------------- Te gebruiken Sudo code --------------------------------
	
		//	begin
		//		initialisaties;
		//		repeat
		//			wait(event);
		//			case event of
		//				NetworkLayerReady:	
		//						buffer message en verstuur in nieuw dataframe;
		//				FrameArrival:
		//						if	Dataframe
		//						then	begin
		//								if 	onverwacht sequencenr and
		//									geen Nak verstuurd voor huidig FrameExpected
		//								then	stuur Nakframe;
		//								if	sequencenr in receiving window and
		//									nog niet geaccepteerd
		//								then	begin
		//											plaats frame in buffer;
		//											frames aan onderkant rec. win. naar NL;
		//											aanpassen window administratie;
		//											voor elk frame start/reset Acktimer;
		//									end;
		//							end;
		//						if	Nak (of 3 x dupl. Ack) 
		//							and gevraagd sequencenr. zit in sending window
		//						then	stuur aangeduid frame opnieuw;
		//
		//						// afrondende acties voor bovenstaande arrivals
		//						// en na ontvangst van expliciet Ackframe
		//						stop timer(s) van bevestigde frame(s) en 
		//						schuif ondergrens van sending window op;
		//
		//				ChecksumError:
		//						stuur Nak voor verwachtte dataframe;
		//
		//				TimeOut:
		//						Stuur dataframe, waarop timeout ontstond, opnieuw;
		//
		//				NetworkLayerIdle:	// timeout van Acktimer
		//						stuur expliciet Ackframe  voor huidig receiving window;
		//				end; // end of case
		//
		//			if	sending window niet vol
		//			then	netwerklaag mag pakketten aanleveren;
		//			else	netwerklaag moet geblokkeerd worden;
		//		until doomsday;
		//	end; // end protocol-6
	
	//-------------------------------- /Te gebruiken Sudo code --------------------------------



